package com.glodon.paas.search.index;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.core.MediaType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.glodon.paas.exception.PaasServerExceptionFactory;
import com.glodon.paas.search.model.IndexBase;
import com.glodon.paas.search.util.SearchConstants;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;

/**
 * 索引服务.
 * 
 * @author botao.liao
 * 
 */
@Component
public class IndexService {
    private Logger logger = LoggerFactory.getLogger(IndexService.class);
    private static final ClientConfig clientConfig;

    static {
        clientConfig = new DefaultClientConfig();
        clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    }

    @Value("${api.internal.es.url}")
    private String esUrl;

    /**
     * @param index
     * @param type
     * @param doc
     *            欲索引的Map对象
     * @param key
     *            索引Id在Map对对应的Key名称
     * @return 索引成功，返回true，否则返回false.
     * @throws IOException
     */
    public boolean index(String index, String type, IndexBase base) {
        boolean success;
        logger.info("indexing index[{}] type[{}]: {}", index, type, base.getName());
        StringBuilder url = new StringBuilder(esUrl.trim());
        // 这里索引ID用fileId
        url.append("/").append(index).append("/").append(type).append("/").append(base.getId());
        WebResource resource = Client.create(clientConfig).resource(url.toString());
        ClientResponse response = resource.type(MediaType.APPLICATION_JSON_TYPE).put(ClientResponse.class, base);
        logger.debug("index response: {}", response);
        if (response.getStatus() > 206) {
            logger.error("failed to index doc {}, for reason: {}", base.getName(), response.getEntity(String.class));
            success = false;
        } else {
            success = true;
        }
        response.close();
        return success;
    }

    /**
     * @param index
     * @param type
     * @param doc
     *            欲索引的Map对象
     * @param key
     *            索引Id在Map对对应的Key名称
     * @return 索引成功，返回true，否则返回false.
     * @throws IOException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public boolean update(String index, String type, String id, Map params) {
        boolean success;
        logger.info("updating index[{}] type[{}]: {}", index, type, id);
        StringBuilder url = new StringBuilder(esUrl.trim());
        // 这里索引ID用fileId
        url.append("/").append(index).append("/").append(type).append("/").append(id).append("/_update");
        WebResource resource = Client.create(clientConfig).resource(url.toString());
        Map mergeMap = new HashMap();
        mergeMap.put("doc", params);
        ClientResponse response = resource.type(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, mergeMap);
        logger.debug("index response: {}", response);
        if (response.getStatus() > 206) {
            logger.error("failed to update doc {}, for reason: {}", id, response.getEntity(String.class));
            success = false;
        } else {
            success = true;
        }
        response.close();
        return success;
    }

    /**
     * 根据fileId删除索引.
     * 
     * @param index
     * @param type
     * @param fileId
     * @return
     */
    public boolean delete(String index, String type, String fileId) {
        boolean success;
        StringBuilder url = new StringBuilder(esUrl.trim());
        url.append("/").append(index).append("/").append(type);
        if (SearchConstants.TYPE_DOC.equals(type)) {
            url.append("/").append(fileId);
        } else if (SearchConstants.TYPE_RVT.equals(type)) {
            url.append("/_query?q=fileId:").append(fileId);
        } else {
            throw PaasServerExceptionFactory.nosupport("not supported databag type " + type);
        }
        WebResource resource = Client.create(clientConfig).resource(url.toString());
        ClientResponse response = resource.type(MediaType.APPLICATION_JSON_TYPE).delete(ClientResponse.class);
        if (response.getStatus() > 206) {
            logger.error("failed to delete index: {}, for reason: {}", fileId, response.getEntity(String.class));
            success = false;
        } else {
            success = true;
        }
        return success;
    }

    public void setEsUrl(String esUrl) {
        this.esUrl = esUrl;
    }
}
